package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.ISocDispatchCompanyEmpDAO;
import org.jsola.hr.dto.SocDispatchCompanyEmpAddDTO;
import org.jsola.hr.dto.SocDispatchCompanyEmpUpdateDTO;
import org.jsola.hr.entity.SocDispatchCompanyEmpDO;
import org.jsola.hr.entity.SocDispatchEmpAddDO;
import org.jsola.hr.entity.SocDispatchEmpLessDO;
import org.jsola.hr.query.SocDispatchCompanyEmpQuery;
import org.jsola.hr.service.ISocDispatchCompanyEmpService;
import org.jsola.hr.service.ISocDispatchEmpAddService;
import org.jsola.hr.service.ISocDispatchEmpLessService;
import org.jsola.hr.vo.SocDispatchCompanyEmpDetailsVO;
import org.jsola.hr.vo.SocDispatchCompanyEmpListVO;
import org.jsola.hr.vo.SocDispatchCompanyEmpVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 社保派单公司记录_员工表
 *
 * @author zhr
 */
@Service("hrSocDispatchCompanyEmpServiceImpl")
public class SocDispatchCompanyEmpServiceImpl implements ISocDispatchCompanyEmpService {

    @Autowired
    private ISocDispatchCompanyEmpDAO socDispatchCompanyEmpDAO;

    @Autowired
    private ISocDispatchEmpAddService socDispatchEmpAddService;

    @Autowired
    private ISocDispatchEmpLessService socDispatchEmpLessService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SocDispatchCompanyEmpVO save(SocDispatchCompanyEmpAddDTO socDispatchCompanyEmpAddDTO, TokenUser tokenUser) {
        // 转DO
        SocDispatchCompanyEmpDO socDispatchCompanyEmpDO = socDispatchCompanyEmpAddDTO.to(SocDispatchCompanyEmpDO.class);
        // 保存
        socDispatchCompanyEmpDO = save(socDispatchCompanyEmpDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return socDispatchCompanyEmpDO.to(SocDispatchCompanyEmpVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(SocDispatchCompanyEmpUpdateDTO socDispatchCompanyEmpUpdateDTO, TokenUser tokenUser) {
        //转DO
        SocDispatchCompanyEmpDO socDispatchCompanyEmpDO = socDispatchCompanyEmpUpdateDTO.to(SocDispatchCompanyEmpDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(socDispatchCompanyEmpDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... socDispatchCompanyEmpIds) {
        return deleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) socDispatchCompanyEmpIds);
    }


    @Override
    public SocDispatchCompanyEmpVO selectById(String socDispatchCompanyEmpId, String siteId) {
        SocDispatchCompanyEmpDO socDispatchCompanyEmpDO = selectDOById(socDispatchCompanyEmpId, siteId);
        if (socDispatchCompanyEmpDO == null) {
            return null;
        }
        return socDispatchCompanyEmpDO.to(SocDispatchCompanyEmpVO.class);
    }

    @Override
    public List<SocDispatchCompanyEmpListVO> select(SocDispatchCompanyEmpQuery socDispatchCompanyEmpQuery, String siteId) {
        List<SocDispatchCompanyEmpDO> socDispatchCompanyEmpDOList = selectDO(socDispatchCompanyEmpQuery, siteId);
        if(CollectionUtils.isEmpty(socDispatchCompanyEmpDOList)) {
            return socDispatchCompanyEmpDOList == null ? null : new ArrayList<>();
        }
        return socDispatchCompanyEmpDOList.stream()
                .map(socDispatchCompanyEmpDO -> socDispatchCompanyEmpDO.to(SocDispatchCompanyEmpListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(SocDispatchCompanyEmpQuery socDispatchCompanyEmpQuery, String siteId) {
        Example example = buildExample(socDispatchCompanyEmpQuery,siteId);
        return socDispatchCompanyEmpDAO.selectCountByExample(example);
    }

    @Override
    public Page<SocDispatchCompanyEmpListVO> selectPage(SocDispatchCompanyEmpQuery socDispatchCompanyEmpQuery, String siteId) {
        Example example = buildExample(socDispatchCompanyEmpQuery,siteId);
        Page<SocDispatchCompanyEmpDO> page = socDispatchCompanyEmpDAO.selectPageByExample(example,
                socDispatchCompanyEmpQuery.getPageNo(),
                socDispatchCompanyEmpQuery.getPageSize());

        return page.to(SocDispatchCompanyEmpListVO.class);
    }

    @Override
    public SocDispatchCompanyEmpDO selectDOById(String socDispatchCompanyEmpId, String siteId) {
        return listById(socDispatchCompanyEmpId, siteId);
    }

    @Override
    public List<SocDispatchCompanyEmpDO> selectDO(SocDispatchCompanyEmpQuery socDispatchCompanyEmpQuery, String siteId) {
        Example example = buildExample(socDispatchCompanyEmpQuery,siteId);
        return socDispatchCompanyEmpDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void batchSave(List<SocDispatchCompanyEmpDO> companyEmpList, TokenUser tokenUser) {
        socDispatchCompanyEmpDAO.insertListAndSetId(companyEmpList);
    }

    @Override
    public List<SocDispatchCompanyEmpDetailsVO> listBySocDispatchCompanyIds(String siteId, String... dispatchCompanyIds) {
        if (dispatchCompanyIds == null || dispatchCompanyIds.length == 0) {
            return null;
        }
        Example example = new Example(SocDispatchCompanyEmpDO.class);
        example.and()
                .andIn("socDispatchCompanyId", Arrays.asList(dispatchCompanyIds))
                .andEqualTo("siteId", siteId);
        example.orderBy("id");
        List<SocDispatchCompanyEmpDO> empList = socDispatchCompanyEmpDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empList)) {
            return null;
        }
        // 实体转换
        List<SocDispatchCompanyEmpDetailsVO> empDetailsList = empList.stream()
                .map(empInfo -> empInfo.to(SocDispatchCompanyEmpDetailsVO.class))
                .collect(Collectors.toList());

        // 增员
        String[] empAddIds = empList.parallelStream()
                .filter(SocDispatchCompanyEmpDO::getAddOrLess)
                .map(SocDispatchCompanyEmpDO::getSocDispatchEmpId)
                .toArray(String[]::new);
        if (empAddIds.length > 0) {
            List<SocDispatchEmpAddDO> empAddList = socDispatchEmpAddService.listByIds(siteId, empAddIds);
            if (!CollectionUtils.isEmpty(empAddList)) {
                Map<String, SocDispatchEmpAddDO> empAddMap = empAddList.parallelStream().collect(
                        Collectors.toMap(SocDispatchEmpAddDO::getId, Function.identity())
                );
                empDetailsList.parallelStream()
                        .filter(SocDispatchCompanyEmpDetailsVO::getAddOrLess)
                        .forEach(
                                empDetails -> {
                                    SocDispatchEmpAddDO socEmpAdd = empAddMap.get(empDetails.getSocDispatchEmpId());
                                    if (Objects.nonNull(socEmpAdd)) {
                                        empDetails.setStatus(socEmpAdd.getStatus());

                                        empDetails.setPersonalPfAmount(socEmpAdd.getPersonalPfAmount());
                                        empDetails.setPersonalSocAmount(socEmpAdd.getPersonalSocAmount());
                                        empDetails.setPersonalAmount(socEmpAdd.getPersonalAmount());

                                        empDetails.setCompanyPfAmount(socEmpAdd.getCompanyPfAmount());
                                        empDetails.setCompanySocAmount(socEmpAdd.getCompanySocAmount());
                                        empDetails.setCompanyAmount(socEmpAdd.getCompanyAmount());
                                        empDetails.setAllAmount(socEmpAdd.getAllAmount());
                                    }
                                }
                        );
            }
        }

        // 减员
        String[] empLessIds = empList.parallelStream()
                .filter(companyEmp -> !companyEmp.getAddOrLess())
                .map(SocDispatchCompanyEmpDO::getSocDispatchEmpId)
                .toArray(String[]::new);
        if (empLessIds.length > 0) {
            List<SocDispatchEmpLessDO> empLessList = socDispatchEmpLessService.listByIds(siteId, empLessIds);
            if (!CollectionUtils.isEmpty(empLessList)) {
                Map<String, SocDispatchEmpLessDO> empLessMap = empLessList.parallelStream().collect(
                        Collectors.toMap(SocDispatchEmpLessDO::getId, Function.identity())
                );
                empDetailsList.parallelStream()
                        .filter(empDetails -> !empDetails.getAddOrLess())
                        .forEach(
                                empDetails -> {
                                    SocDispatchEmpLessDO socEmpLess = empLessMap.get(empDetails.getSocDispatchEmpId());
                                    if (Objects.nonNull(socEmpLess)) {
                                        empDetails.setStatus(socEmpLess.getStatus());
                                    }
                                }
                        );
            }
        }
        return empDetailsList;
    }

    @Override
    public List<SocDispatchCompanyEmpDO> listBySocDispatchEmpIds(String socDispatchCompanyId, List<String> socDispatchEmpIdList, String siteId) {
        if (CollectionUtils.isEmpty(socDispatchEmpIdList)) {
            return null;
        }
        Example example = new Example(SocDispatchCompanyEmpDO.class);
        example.and()
                .andEqualTo("socDispatchCompanyId", socDispatchCompanyId)
                .andIn("socDispatchEmpId", socDispatchEmpIdList)
                .andEqualTo("siteId", siteId);

        return socDispatchCompanyEmpDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example

     * @param socDispatchCompanyEmpQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(SocDispatchCompanyEmpQuery socDispatchCompanyEmpQuery, String siteId) {
        Example example = new Example(SocDispatchCompanyEmpDO.class);
        example.and()
                .andEqualTo("siteId", siteId);
        if (socDispatchCompanyEmpQuery.getSocDispatchId() != null) {
            example.and().andEqualTo("socDispatchId", socDispatchCompanyEmpQuery.getSocDispatchId());
        }
        if (socDispatchCompanyEmpQuery.getAddOrLess() != null) {
            example.and().andEqualTo("addOrLess", socDispatchCompanyEmpQuery.getAddOrLess());
        }
        if (socDispatchCompanyEmpQuery.getSocDispatchCompanyId() != null) {
            example.and().andEqualTo("socDispatchCompanyId", socDispatchCompanyEmpQuery.getSocDispatchCompanyId());
        }
        if (socDispatchCompanyEmpQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", socDispatchCompanyEmpQuery.getCompanyId());
        }
        if (socDispatchCompanyEmpQuery.getSocDispatchEmpId() != null) {
            example.and().andEqualTo("socDispatchEmpId", socDispatchCompanyEmpQuery.getSocDispatchEmpId());
        }
        if (socDispatchCompanyEmpQuery.getChildCompanyId() != null) {
            example.and().andEqualTo("childCompanyId", socDispatchCompanyEmpQuery.getChildCompanyId());
        }
        // 排序
        ExampleKit.setExampleOrder(example,socDispatchCompanyEmpQuery.getOrders());
        return example;
    }
}




